<template>
  <div class="the-map-component">
    <v-stage ref="ref-stage" :config="stageConfig">
      <v-layer>
        <v-image
          :config="{
          image:mapImage,
          width:mapSize,
          height:mapSize,
          opacity:0.5
        }"
        ></v-image>
        <!-- <v-rect
          :config="{
          x: 0,
          y: 0,
          width: 100,
          height: 100,
          fill: 'red',
          shadowBlur: 10
        }"
        />-->
      </v-layer>
      <v-layer ref="lines-layer"></v-layer>
    </v-stage>
    <hr />
    <br />
    <!-- <event-time></event-time> -->
  </div>
</template>

<script>
import axios from "axios";
import konva from "konva";
import Gradient from "javascript-color-gradient";
import * as Color from "color";
import { map, clamp, sortBy } from "lodash";
import EventTime from "./EventTime";

const Savage_Main_Squad_DownInZone =
  "http://m.tuniucdn.com/fb2/t1/G6/M00/F0/B9/Cii-U178yXKIC8L3AAgiAB6O7_oAANa6ANNhtcACCIY84.json";

const MAP_IMAGES = {
  Vikendi:
    "http://n1-q.mafengwo.net/s16/M00/1F/16/CoUBUl6J6-WAfTq9ABN1dkMMLI4971.jpg#DihorOtok_Main",
  "Erangel (Remastered)":
    "http://n1-q.mafengwo.net/s16/M00/24/CD/CoUBUl6J8CGAZ8FWACwGssFmNzs911.jpg#Baltic_Main.jpg.jpg",
  Miramar:
    "http://b1-q.mafengwo.net/s16/M00/25/07/CoUBUl6J8DuABPwhAB3VGbsEWx0692.jpg#Desert_Main.jpg.jpg",
  Erangel:
    "http://n1-q.mafengwo.net/s16/M00/25/14/CoUBUl6J8E-AbIDmABcvo6NWiPE512.jpg#Erangel_Main.jpg.jpg",
  Sanhok:
    "http://m.tuniucdn.com/fb2/t1/G6/M00/F0/BC/Cii-TF781C2IcJj7AA590so7b_UAANa_AI4S9UADn3q184.jpg#Savage_Main.jpg.jpg"
};
const MAP_LENGTH_CENTIMETERS = {
  Vikendi: 612000,
  "Erangel (Remastered)": 816000,
  Miramar: 816000,
  Erangel: 816000,
  Sanhok: 408000
};

const GridSize = {
  Sanhok: 5100
};

const MAP_NAME = "Sanhok";

const toScale = (pubgMapSize, mapSize, n) =>
  (n / pubgMapSize) * mapSize * (pubgMapSize === 816000 ? 0.99609375 : 1);

const DRAW_MAP_SIZE = 1000;
export default {
  name: "SafetyzoneGridHeatmap",
  data() {
    return {
      mapSize: DRAW_MAP_SIZE,
      stageConfig: {
        width: DRAW_MAP_SIZE,
        height: DRAW_MAP_SIZE,
        draggable: true
      },
      mapName: MAP_NAME,
      mapImageLink: MAP_IMAGES[MAP_NAME],
      mapImage: (_ => {
        let img = new window.Image();
        img.src = MAP_IMAGES[MAP_NAME];
        return img;
      })(),
      mapScale: 1,
      offsetX: 0,
      offsetY: 0
    };
  },
  computed: {},
  components: {
    EventTime
  },
  async mounted() {
    let data = await this.getRemoteData(Savage_Main_Squad_DownInZone);
    let mapSize = DRAW_MAP_SIZE;
    let rawMapSize = MAP_LENGTH_CENTIMETERS[MAP_NAME];
    const _scale = mapSize / rawMapSize;
    // debugger;

    let colorTable = [
      "rgba(0,255,128,0.75)",
      "rgba(0,0,102,0.75)",
      "rgba(0,153,255,0.75)",
      "rgba(204,0,102,0.75)",
      "rgba(51,153,153,0.75)",
      "rgba(46,199,201,0.75)",
      "rgba(182,162,222,0.75)",
      "rgba(90,177,239,0.75)",
      "rgba(255,185,128,0.75)",
      "rgba(216,122,128,0.75)",
      "rgba(141,152,179,0.75)",
      "rgba(193,46,52,0.75)",
      "rgba(230,182,0,0.75)",
      "rgba(0,152,217,0.75)",
      "rgba(43,130,29,0.75)",
      "rgba(0,24,82,0.75)"
    ];

    let zoneNames = Object.keys(data);
    // let index = 2;
    let points = [];

    for (let index = 0; index < zoneNames.length; index++) {
      let c = colorTable[index % colorTable.length];
      points = points.concat(
        data[zoneNames[index]].map(e => {
          return new konva.Circle({
            x: e.x * _scale,
            y: e.y * _scale,
            radius: 1.5,
            fill: c,
            strokeWidth: 0
          });
        })
      );
    }

    let grids_and_text = (_ => {
      let L = MAP_LENGTH_CENTIMETERS[MAP_NAME] / GridSize[MAP_NAME];
      let konva_eles = [];
      for (let xi = 0; xi < L; xi++) {
        for (let yi = 0; yi < L; yi++) {
          konva_eles.push(
            new konva.Rect({
              x: xi * GridSize[MAP_NAME] * _scale,
              y: yi * GridSize[MAP_NAME] * _scale,
              width: GridSize[MAP_NAME] * _scale,
              height: GridSize[MAP_NAME] * _scale,
              fill: "rgba(0,0,0,0)",
              stroke: "rgba(0,0,0,1)",
              strokeWidth: 0.05
            })
          );
          konva_eles.push(
            new konva.Text({
              x: xi * GridSize[MAP_NAME] * _scale,
              y: yi * GridSize[MAP_NAME] * _scale,
              text: `[${xi},${yi}]`,
              fontSize:GridSize[MAP_NAME]/3*_scale,
              fill:"rgba(0,0,0,0.8)"
            })
          );
        }
      }
      return konva_eles;
    })();

    // return;

    // debugger
    let v_layer = this.$refs["lines-layer"];
    /**@type {konva.Layer} */
    let layer = v_layer.getNode();
    // layer.add(...grids_normal);
    layer.add(...points);
    // layer.add(...grids_and_text);
    layer.draw();

    const MIN_SCALE = 1;
    const MAX_SCALE = 50;
    let v_stage = this.$refs["ref-stage"];
    /**@type {konva.Stage} */
    let stage = v_stage.getNode();
    let v = this;

    let handleZoom =
      /**
       * @param {Number} scaleDelta
       * @param {Number} layerX?
       * @param {Number} layerY?
       */
      (scaleDelta, layerX, layerY) => {
        if (!layerX) layerX = DRAW_MAP_SIZE / 2;
        if (!layerY) layerY = DRAW_MAP_SIZE / 2;
        let newScale = clamp(v.mapScale * scaleDelta, MIN_SCALE, MAX_SCALE);
        let mousePointX = layerX / v.mapScale - v.offsetX / v.mapScale;
        let mousePointY = layerY / v.mapScale - v.offsetY / v.mapScale;
        let offsetX = -(mousePointX - layerX / newScale) * newScale;
        let offsetY = -(mousePointY - layerY / newScale) * newScale;
        offsetX = clamp(offsetX, -(newScale - 1) * DRAW_MAP_SIZE, 0);
        offsetY = clamp(offsetY, -(newScale - 1) * DRAW_MAP_SIZE, 0);
        // debugger
        v.mapScale = newScale;
        v.offsetX = offsetX;
        v.offsetY = offsetY;
        // debugger;
        stage.scaleX(newScale);
        stage.scaleY(newScale);
        stage.x(offsetX);
        stage.y(offsetY);
        stage.batchDraw();
      };
    stage.dragBoundFunc(pos => {
      // debugger;
      let { x, y } = pos;
      x = clamp(x, -(this.mapScale - 1) * DRAW_MAP_SIZE, 0);
      y = clamp(y, -(this.mapScale - 1) * DRAW_MAP_SIZE, 0);
      return {
        x,
        y
      };
    });
    stage.on("dragend", ev => {
      // debugger
      let x = ev.target.x();
      let y = ev.target.y();
      x = clamp(x, -(this.mapScale - 1) * DRAW_MAP_SIZE, 0);
      y = clamp(y, -(this.mapScale - 1) * DRAW_MAP_SIZE, 0);
      stage.x(x);
      stage.y(y);
      stage.batchDraw();
    });
    stage.on("wheel", ev => {
      console.log(ev);
      ev.evt.preventDefault();
      const scaleDelta = ev.evt.deltaY > 0 ? 1 / 1.2 : 1.2;
      handleZoom(scaleDelta, ev.evt.layerX, ev.evt.layerY);
    });
    // debugger;
  },
  methods: {
    getRemoteData(link) {
      return new Promise(resolve => {
        axios
          .get(link)
          .then(axresp => {
            resolve(axresp.data);
          })
          .catch(axerr => {
            debugger;
          });
      });
    }
  }
};
</script>

<!-- Add "scoped" attribute to limit CSS to this component only -->
<style lang="less" scoped>
@mapSize: 800px;
.the-map-component {
  // display: flex;
  #map {
    width: @mapSize;
    height: @mapSize;
  }
  .h-check-players {
  }
}
</style>
